<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="10">
        <div class="grid-content bg-purple">
          <el-card class="box-card" style="padding-bottom: 20px">
            <div slot="header" class="clearfix">
              <span>{{ $t('AbpIdentity[\'OrganizationTree\']') }}</span>
              <el-button style="float: right; padding: 3px 0" type="text" @click="openDialog_createOu"> <i class="el-icon-plus" />{{ $t('AbpIdentity[\'AddRootUnit\']') }}</el-button>
            </div>
            <el-tree
              ref="ouTree"
              v-loading="treeContext.loading"
              highlight-current
              :node-key="treeContext.nodeKey"
              :props="treeContext.props"
              :data="treeContext.treeData"
              :expand-on-click-node="false"
              :draggable="treeContext.draggable"
              @node-click="click_ouNode"
              @node-drop="drop_ouNode"
              @node-drag-enter="(_, enterNode) => enterNode.expanded = true"
            >
              <span slot-scope="{ node, data }" class="custom-tree-node">
                <span>{{ node.label }}</span>
                <span>
                  <el-dropdown trigger="click" @command="clickDropDown_ouAction">
                    <span class="el-dropdown-link" @click.stop>
                      <b>···</b>
                    </span>
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item :command="{ action: 'edit', data: data }">{{ $t('AbpIdentity[\'Edit\']') }}</el-dropdown-item>
                      <el-dropdown-item :command="{ action: 'addSubOu', data: data }">{{ $t('AbpIdentity[\'AddSubUnit\']') }}</el-dropdown-item>
                      <el-dropdown-item :command="{ action: 'delete', data: data }">{{ $t('AbpIdentity[\'Delete\']') }}</el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                </span>
              </span>
            </el-tree>
          </el-card>
        </div>
      </el-col>
      <el-col :span="14">
        <div class="grid-content bg-purple-light">
          <el-tabs ref="tab" type="border-card">
            <el-tab-pane :label="$t('AbpIdentity[\'Members\']')">
              <el-button
                type="primary"
                style="float: right"
                @click="openDialog_addMember"
              >
                <i class="el-icon-plus" />{{ $t('AbpIdentity[\'AddMember\']') }}
              </el-button>
              <el-table
                v-loading="memberListLoading"
                :data="memberList"
                :element-loading-text="$t('AbpIdentity[\'LoadingWithThreeDot\']')"
                :empty-text="memberListEmptyText"
                fit
                highlight-current-row
              >
                <el-table-column >
                  <template slot-scope="scope">
                    <el-button type="danger" circle @click="click_deleteMember(scope.row.id)" icon="el-icon-minus"></el-button>
                  </template>
                </el-table-column>
                <el-table-column :label="$t('BookStore2[\'DisplayName:UserName\']')" prop="userName" sortable="custom">
                  <template slot-scope="scope">
                    {{ scope.row.userName }}
                  </template>
                </el-table-column>
                <el-table-column :label="$t('AbpIdentity[\'DisplayName:Name\']')" prop="name" sortable="custom">
                  <template slot-scope="scope">
                    {{ scope.row.name }}
                  </template>
                </el-table-column>
                <el-table-column :label="$t('AbpIdentity[\'DisplayName:Email\']')" prop="email" sortable="custom">
                  <template slot-scope="scope">
                    {{ scope.row.email }}
                  </template>
                </el-table-column>
              </el-table>
              <div class="block" style="margin-top: 10px">
                <el-pagination
                  :page-sizes="memberPageContext.pageSizes"
                  :page-size.sync="memberListContext.maxResultCount"
                  :current-page.sync="memberPageContext.currentPage"
                  :total="memberPageContext.totalCount"
                  layout="total, sizes, prev, pager, next, jumper"
                  @size-change="fetchMemberList"
                  @current-change="memberList_handleCurrentChange"
                />
              </div>
            </el-tab-pane>
            <el-tab-pane :label="$t('AbpIdentity[\'Roles\']')">
              <el-button
                type="primary"
                style="float: right"
                @click="openDialog_addRole"
              >
                <i class="el-icon-plus" />{{ $t('AbpIdentity[\'AddRole\']') }}
              </el-button>
              <el-table
                v-loading="roleListLoading"
                :data="roleList"
                :element-loading-text="$t('AbpIdentity[\'LoadingWithThreeDot\']')"
                :empty-text="roleListEmptyText"
                fit
                highlight-current-row
              >
                <el-table-column >
                  <template slot-scope="scope">
                    <el-button type="danger" circle @click="click_deleteRole(scope.row.id)" icon="el-icon-minus"></el-button>
                  </template>
                </el-table-column>
                <el-table-column :label="$t('AbpIdentity[\'DisplayName:RoleName\']')" prop="name" sortable="custom">
                  <template slot-scope="scope">
                    {{ scope.row.name }}
                  </template>
                </el-table-column>
              </el-table>
              <div class="block" style="margin-top: 10px">
                <el-pagination
                  :page-sizes="rolePageContext.pageSizes"
                  :page-size.sync="roleListContext.maxResultCount"
                  :current-page.sync="rolePageContext.currentPage"
                  :total="rolePageContext.totalCount"
                  layout="total, sizes, prev, pager, next, jumper"
                  @size-change="fetchRoleList"
                  @current-change="roleList_handleCurrentChange"
                />
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </el-col>
    </el-row>
    <create-or-edit-ou :visible.sync="ouDialogVisible" :context="ouDialogCtx" @saveSucceed="onSucceed_ouSave" />
    <add-member :visible.sync="addMemberDialogVisible" :context="addMemberCtx" />
    <add-role :visible.sync="addRoleDialogVisible" :context="addRoleCtx" />
  </div>
</template>

<script>
import {
  getAllList as getOuAllList,
  deleteById as deleteOuById,
  move as moveOu,
  getMemberList,
  deleteMember,
  getRoleList,
  deleteRole
} from '@/api/administration/organizationUnit/organizationUnit'
import CreateOrEditOu from '@/views/administration/identity/organizationUnit/components/createOrEditOu'
import AddMember from '@/views/administration/identity/organizationUnit/components/addMember'
import AddRole from '@/views/administration/identity/organizationUnit/components/addRole'
import { convertTree } from '@/utils/treeUtil'

export default {
  name: 'OrganizationUnit',
  components: { CreateOrEditOu, AddMember, AddRole },
  data() {
    return {
      listLoading: true,
      treeContext: {
        loading: false,
        draggable: true,
        props: {
          label: 'displayName',
          children: 'children'
        },
        nodeKey: 'id',
        data: [],
        treeData: []
      },
      ouDialogVisible: false,
      ouDialogCtx: {
        title: '',
        actionMode: '',
        id: ''
      },
      memberList: null,
      memberListLoading: false,
      memberListEmptyText: this.$t('AbpIdentity[\'SelectAnOrganizationUnitToSeeMembers\']'),
      memberPageContext: {
        pageSizes: [10, 25, 50, 100],
        totalCount: 0,
        currentPage: 1
      },
      memberListContext: {
        filter: '',
        sorting: '',
        skipCount: 0,
        maxResultCount: 10
      },
      addMemberDialogVisible: false,
      addMemberCtx: {
        ouId: ''
      },
      roleList: null,
      roleListLoading: false,
      roleListEmptyText: this.$t('AbpIdentity[\'SelectAnOrganizationUnitToSeeRoles\']'),
      rolePageContext: {
        pageSizes: [10, 25, 50, 100],
        totalCount: 0,
        currentPage: 1
      },
      roleListContext: {
        filter: '',
        sorting: '',
        skipCount: 0,
        maxResultCount: 10
      },
      addRoleDialogVisible: false,
      addRoleCtx: {
        ouId: ''
      }
    }
  },
  created() {
    this.fetchOuTree()
  },
  methods: {
    fetchOuTree() {
      this.treeContext.loading = true
      getOuAllList().then(resp => {
        this.treeContext.data = resp.items
        this.treeContext.treeData = convertTree(this.treeContext.data)
      }).finally(() => {
        this.treeContext.loading = false
      })
    },
    fetchMemberList() {
      const ouDataNode = this.$refs.ouTree.getCurrentNode()
      this.memberListLoading = true
      getMemberList(ouDataNode.id, this.memberListContext).then(resp => {
        this.memberList = resp.items
        this.memberPageContext.totalCount = resp.totalCount
        if (resp.totalCount === 0) {
          this.memberListEmptyText = this.$t('AbpIdentity[\'NoDataAvailableInDatatable\']')
        }
      }).finally(() => {
        this.memberListLoading = false
      })
    },
    memberList_handleCurrentChange(currentPage) {
      this.memberListContext.skipCount = (currentPage - 1) * this.memberListContext.maxResultCount
      this.fetchMemberList()
    },
    click_deleteMember(memberId) {
      this.$confirm(this.$t('AbpIdentity[\'AreYouSure\']')).then(async _ => {
        const ouDataNode = this.$refs.ouTree.getCurrentNode()
        await deleteMember(ouDataNode.id, memberId)
        this.$message({
          message: this.$t('AbpIdentity[\'Ok\']'),
          type: 'success'
        })
        this.fetchMemberList()
      }).catch(_ => {})
    },
    fetchRoleList() {
      const ouDataNode = this.$refs.ouTree.getCurrentNode()
      this.roleListLoading = true
      getRoleList(ouDataNode.id, this.roleListContext).then(resp => {
        this.roleList = resp.items
        this.rolePageContext.totalCount = resp.totalCount
        if (resp.totalCount === 0) {
          this.roleListEmptyText = this.$t('AbpIdentity[\'NoDataAvailableInDatatable\']')
        }
      }).finally(() => {
        this.roleListLoading = false
      })
    },
    roleList_handleCurrentChange(currentPage) {
      this.roleListContext.skipCount = (currentPage - 1) * this.roleListContext.maxResultCount
      this.fetchRoleList()
    },
    click_deleteRole(roleId) {
      this.$confirm(this.$t('AbpIdentity[\'AreYouSure\']')).then(async _ => {
        const ouDataNode = this.$refs.ouTree.getCurrentNode()
        await deleteRole(ouDataNode.id, roleId)
        this.$message({
          message: this.$t('AbpIdentity[\'Ok\']'),
          type: 'success'
        })
        this.fetchRoleList()
      }).catch(_ => {})
    },
    clickDropDown_ouAction(ctx) {
      switch (ctx.action) {
        case 'edit':
          this.openDialog_editOu(ctx.data)
          break
        case 'addSubOu':
          this.openDialog_createSubOu(ctx.data)
          break
        case 'delete':
          this.$confirm(this.$t('AbpIdentity[\'AreYouSure\']')).then(async _ => {
            await deleteOuById(ctx.data.id)
            this.$message({
              message: this.$t('AbpIdentity[\'Ok\']'),
              type: 'success'
            })
            this.$refs.ouTree.remove(ctx.data)
          }).catch(e => {
            console.log(e)
          })
          break
      }
    },
    click_ouNode(data) {
      this.fetchMemberList()
      this.fetchRoleList()
    },
    dragEnter_ouNode(node, enterNode, event) {
      enterNode.expanded = true
    },
    async drop_ouNode(node, lastEnterNode, action, event) {
      this.treeContext.loading = true
      node = this.$refs.ouTree.getNode(node.data.id) // 获取最新状态的node
      await moveOu(node.data.id, { newParentId: action !== 'inner' && node.level === 1 ? null : lastEnterNode.data.id })
      this.treeContext.loading = false
    },
    openDialog_createOu() {
      this.ouDialogVisible = true
      this.ouDialogCtx = {
        title: this.$t('AbpIdentity[\'NewOrganizationUnit\']'),
        actionMode: 'create'
      }
    },
    openDialog_createSubOu(ou) {
      this.ouDialogVisible = true
      this.ouDialogCtx = {
        title: this.$t('AbpIdentity[\'NewOrganizationUnit\']'),
        actionMode: 'createSub',
        parentId: ou.id,
        parentOuDisplayName: ou.displayName
      }
    },
    openDialog_editOu(ou) {
      this.ouDialogVisible = true
      this.ouDialogCtx = {
        title: this.$t('AbpIdentity[\'Edit\']'),
        actionMode: 'edit',
        id: ou.id
      }
    },
    openDialog_addMember() {
      const ouDataNode = this.$refs.ouTree.getCurrentNode()
      if (!ouDataNode) {
        this.$message({ message: this.$t('AbpIdentity[\'SelectAnOrganizationUnitToAddMembers\']'), type: 'warning' })
        return
      }
      this.addMemberDialogVisible = true
      this.addMemberCtx = {
        ouId: ouDataNode.id
      }
    },
    openDialog_addRole() {
      const ouDataNode = this.$refs.ouTree.getCurrentNode()
      if (!ouDataNode) {
        this.$message({ message: this.$t('AbpIdentity[\'SelectAnOrganizationUnitToAddRoles\']'), type: 'warning' })
        return
      }
      this.addRoleDialogVisible = true
      this.addRoleCtx = {
        ouId: ouDataNode.id
      }
    },
    onSucceed_ouSave(actionMode, ou) {
      const node = this.$refs.ouTree.getNode(ou.id)
      const parentNode = this.$refs.ouTree.getNode(ou.parentId || '')
      switch (actionMode) {
        case 'create': // 创建
        case 'createSub': // 创建子组织
          this.$refs.ouTree.append(ou, ou.parentId)
          if (parentNode) {
            parentNode.expanded = true
          }
          break
        case 'edit': // 编辑
          node.data.displayName = ou.displayName
          break
      }
    }
  }
}
</script>

<style scoped>

/deep/.el-tabs__item {
  width: 100px;
  height: 58px;
  padding-top: 8px;
  text-align: center;
}

/deep/.el-tabs--border-card>.el-tabs__header {
  background-color: #FFFFFF;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.el-dropdown-link {
  cursor: pointer;
  color: #409EFF;
}
.el-icon-arrow-down {
  font-size: 12px;
}
.demonstration {
  display: block;
  color: #8492a6;
  font-size: 14px;
  margin-bottom: 20px;
}

</style>
